From 7aeeeea16127e984ba2d7e8237a15ba88c108bf0 Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Thu, 29 Jul 2004 12:45:53 +0000 Subject: [PATCH] bitkeeper revision 1.1108.35.2 (4108f181qIC17s1k7tUAzAMnlIZwBA) Add support for getting the xend log. Needed response headers and mime-types in the xend client code. Add command groups in xm help. --- .rootkeys | 1 + tools/python/xen/xend/XendClient.py | 81 ++++++-------- tools/python/xen/xend/XendDmesg.py | 4 +- tools/python/xen/xend/XendLogging.py | 4 + tools/python/xen/xend/server/SrvDmesg.py | 12 ++- tools/python/xen/xend/server/SrvNode.py | 5 +- tools/python/xen/xend/server/SrvXendLog.py | 24 +++++ tools/python/xen/xm/main.py | 118 +++++++++++++++++---- tools/python/xen/xm/shutdown.py | 8 +- 9 files changed, 178 insertions(+), 79 deletions(-) create mode 100644 tools/python/xen/xend/server/SrvXendLog.py diff --git a/.rootkeys b/.rootkeys index 2324eb9159..057be97bd7 100644 --- a/.rootkeys +++ b/.rootkeys @@ -433,6 +433,7 @@ 40c9c469TaZ83ypsrktmPSHLEZiP5w tools/python/xen/xend/server/SrvRoot.py 40c9c469W3sgDMbBJYQdz5wbQweL0Q tools/python/xen/xend/server/SrvServer.py 40c9c469aq7oXrE1Ngqf3_lBqL0RoQ tools/python/xen/xend/server/SrvVnetDir.py +4108f181GtRoD1U9TBuJXMfBbGJwdQ tools/python/xen/xend/server/SrvXendLog.py 40c9c469Y_aimoOFfUZoS-4eV8gEKg tools/python/xen/xend/server/__init__.py 40c9c4692hckPol_EK0EGB16ZyDsyQ tools/python/xen/xend/server/blkif.py 40c9c469N2-b3GqpLHHHPZykJPLVvA tools/python/xen/xend/server/channel.py diff --git a/tools/python/xen/xend/XendClient.py b/tools/python/xen/xend/XendClient.py index 3846fbce76..1bb7a094f2 100644 --- a/tools/python/xen/xend/XendClient.py +++ b/tools/python/xen/xend/XendClient.py @@ -130,7 +130,6 @@ class XendRequest: class XendClientProtocol: """Abstract class for xend clients. """ - def xendRequest(self, url, method, args=None): """Make a request to xend. Implement in a subclass. @@ -176,6 +175,9 @@ class XendClientProtocol: """Handle the data returned in response to the request. """ if data is None: return None + type = self.getHeader('Content-Type') + if type != sxp.mime_type: + return data try: pin = sxp.Parser() pin.input(data); @@ -194,11 +196,22 @@ class XendClientProtocol: """ raise err + def getHeader(self, key): + """Get a header from the response. + Case is ignored in the key. + + @param key: header key + @return: header + """ + raise NotImplementedError() + class SynchXendClientProtocol(XendClientProtocol): """A synchronous xend client. This will make a request, wait for the reply and return the result. """ + resp = None + def xendRequest(self, url, method, args=None): """Make a request to xend. @@ -211,6 +224,7 @@ class SynchXendClientProtocol(XendClientProtocol): if DEBUG: conn.set_debuglevel(1) conn.request(method, url.fullpath(), self.request.data, self.request.headers) resp = conn.getresponse() + self.resp = resp val = self.handleStatus(resp.version, resp.status, resp.reason) if val is None: data = None @@ -220,6 +234,10 @@ class SynchXendClientProtocol(XendClientProtocol): val = self.handleResponse(data) return val + def getHeader(self, key): + return self.resp.getheader(key) + + class AsynchXendClient(http.HTTPClient): """A subclass of twisted's HTTPClient to deal with a connection to xend. Makes the request when connected, and delegates handling responses etc. @@ -245,6 +263,9 @@ class AsynchXendClient(http.HTTPClient): def handleStatus(self, version, status, message): return self.protocol.handleStatus(version, status, message) + def handleHeader(self, key, val): + return self.protocol.handleHeader(key, val) + def handleResponse(self, data): return self.protocol.handleResponse(data) @@ -257,11 +278,12 @@ class AsynchXendClientProtocol(XendClientProtocol): """ def __init__(self): self.err = None + self.headers = {} def xendRequest(self, url, method, args=None): """Make a request to xend. The returned deferred is called when the result is available. - + @param url: xend request url @param method: http method: POST or GET @param args: request arguments (dict) @@ -287,46 +309,11 @@ class AsynchXendClientProtocol(XendClientProtocol): def handleException(self, err): return self.callErrback(err) - def handleResponse(self, data): - if self.err: return self.err - val = XendClientProtocol.handleResponse(self, data) - if isinstance(val, Exception): - self.callErrback(val) - else: - self.callCallback(val) - return val - - def __init__(self): - self.err = None - - def xendRequest(self, url, method, args=None): - """Make a request to xend. The returned deferred is called when - the result is available. - - @param url: xend request url - @param method: http method: POST or GET - @param args: request arguments (dict) - @return: deferred - """ - request = XendRequest(url, method, args) - self.deferred = Deferred() - clientCreator = ClientCreator(reactor, AsynchXendClient, self, request) - clientCreator.connectTCP(url.host, url.port) - return self.deferred - - def callErrback(self, err): - if not self.deferred.called: - self.err = err - self.deferred.errback(err) - return err - - def callCallback(self, val): - if not self.deferred.called: - self.deferred.callback(val) - return val + def handleHeader(self, key, val): + self.headers[key.lower()] = val - def handleException(self, err): - return self.callErrback(err) + def getHeader(self, key): + return self.headers.get(key.lower()) def handleResponse(self, data): if self.err: return self.err @@ -397,9 +384,6 @@ class Xend: def eventurl(self, id=''): return self.url.relative('event/' + str(id)) - def dmesgurl(self, id=''): - return self.url.relative('node/dmesg/' + str(id)) - def xend(self): return self.xendGet(self.url) @@ -408,14 +392,17 @@ class Xend: def xend_node_shutdown(self): return self.xendPost(self.nodeurl(), - {'op' : 'shutdown'}) + {'op' : 'shutdown'}) def xend_node_restart(self): return self.xendPost(self.nodeurl(), - {'op' : 'reboot'}) + {'op' : 'reboot'}) def xend_node_dmesg(self): - return self.xendGet(self.dmesgurl()) + return self.xendGet(self.nodeurl('dmesg')) + + def xend_node_log(self): + return self.xendGet(self.nodeurl('log')) def xend_node_cpu_rrobin_slice_set(self, slice): return self.xendPost(self.nodeurl(), diff --git a/tools/python/xen/xend/XendDmesg.py b/tools/python/xen/xend/XendDmesg.py index b4a5ca9cad..8d070ba45a 100644 --- a/tools/python/xen/xend/XendDmesg.py +++ b/tools/python/xen/xend/XendDmesg.py @@ -1,4 +1,4 @@ -# Copyright (C) 2004 Mike Wray + # Copyright (C) 2004 Mike Wray """Get dmesg output for this node. """ @@ -11,7 +11,7 @@ class XendDmesg: self.xc = xen.lowlevel.xc.new() def info(self): - return [ self.xc.readconsolering() ] + return self.xc.readconsolering() def instance(): diff --git a/tools/python/xen/xend/XendLogging.py b/tools/python/xen/xend/XendLogging.py index 106345e36a..9be84b834c 100644 --- a/tools/python/xen/xend/XendLogging.py +++ b/tools/python/xen/xend/XendLogging.py @@ -44,6 +44,7 @@ class XendLogging: mode='a', maxBytes=self.maxBytes, backupCount=self.backupCount) + self.logfilename = filename self.logfile.setFormatter(Formatter(self.logFileFormat, self.dateFormat)) log = self.getLogger() log.addHandler(self.logfile) @@ -51,6 +52,9 @@ class XendLogging: def getLogFile(self): return self.logfile + def getLogFilename(self): + return self.logfilename + def initLogStderr(self): self.logstderr = StreamHandler() self.logstderr.setFormatter(Formatter(self.logStderrFormat, self.dateFormat)) diff --git a/tools/python/xen/xend/server/SrvDmesg.py b/tools/python/xen/xend/server/SrvDmesg.py index 7580ecded7..2e7b538c55 100644 --- a/tools/python/xen/xend/server/SrvDmesg.py +++ b/tools/python/xen/xend/server/SrvDmesg.py @@ -1,10 +1,12 @@ # Copyright (C) 2004 Mike Wray import os -from SrvDir import SrvDir + from xen.xend import sxp from xen.xend import XendDmesg +from SrvDir import SrvDir + class SrvDmesg(SrvDir): """Xen Dmesg output. """ @@ -16,13 +18,13 @@ class SrvDmesg(SrvDir): def render_GET(self, req): try: if self.use_sxp(req): - req.setHeader("Content-Type", sxp.mime_type) - sxp.show(['dmesg'] + self.info(), out=req) + req.setHeader("Content-Type", "text/plain") + req.write(self.info()) else: req.write('') - req.write('
')
                 self.print_path(req)
-                req.write(self.info()[0])
+                req.write('
')
+                req.write(self.info())
                 req.write('
') return '' except Exception, ex: diff --git a/tools/python/xen/xend/server/SrvNode.py b/tools/python/xen/xend/server/SrvNode.py index e99526fabf..b68b33ea84 100644 --- a/tools/python/xen/xend/server/SrvNode.py +++ b/tools/python/xen/xend/server/SrvNode.py @@ -1,6 +1,7 @@ # Copyright (C) 2004 Mike Wray import os + from SrvDir import SrvDir from xen.xend import sxp from xen.xend import XendNode @@ -14,6 +15,7 @@ class SrvNode(SrvDir): SrvDir.__init__(self) self.xn = XendNode.instance() self.add('dmesg', 'SrvDmesg') + self.add('log', 'SrvXendLog') def op_shutdown(self, op, req): val = self.xn.shutdown() @@ -58,7 +60,8 @@ class SrvNode(SrvDir): req.write('